package com.je.gateway.router.dispatcher;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Strings;
import com.je.gateway.router.GlobalRouterParams;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import org.apache.servicecomb.registry.DiscoveryManager;
import org.apache.servicecomb.registry.api.registry.Microservice;
import org.apache.servicecomb.registry.consumer.MicroserviceManager;
import org.apache.servicecomb.registry.consumer.MicroserviceVersion;
import org.apache.servicecomb.registry.consumer.MicroserviceVersions;
import org.springframework.http.HttpStatus;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class GatewayContractDispatcher extends GatewayAbstractRestDispatcher {

    private static final String LOAD_CONTRACT_URL = "/je/gateway/contract/load";
    private static final String REMOVE_CONTRACT_URL = "/je/gateway/contract/remove";

    @Override
    public int getOrder() {
        return 0;
    }

    @Override
    public void init(Router router) {
        String pattern = GlobalRouterParams.GLOBAL_URL_ROUTER.getPath();
        router.routeWithRegex(pattern).failureHandler(this::onFailure)
                .handler(this::check);
    }

    protected void check(RoutingContext context) {
        String url = context.request().uri();
        if (url.indexOf(LOAD_CONTRACT_URL) >= 0) {
            context.request().response()
                    .setStatusCode(HttpStatus.OK.value())
                    .putHeader("Content-Type", "application/json; charset=utf-8").end(JSON.toJSONString(load()));
            return;
        } else if (url.indexOf(REMOVE_CONTRACT_URL) >= 0) {
            String microKey = context.request().getParam("microKey");
            remove(microKey);
            Map<String, Object> result = new HashMap<>();
            result.put("code", "1000");
            result.put("success", true);
            result.put("message", "清理成功！");
            result.put("data", "清理成功！");
            context.request().response()
                    .setStatusCode(HttpStatus.OK.value())
                    .putHeader("Content-Type", "application/json; charset=utf-8").end(JSON.toJSONString(result));
            return;
        }
        context.next();
    }

    private void remove(String microKey) {
        Map<String, MicroserviceManager> map = DiscoveryManager.INSTANCE.getAppManager().getApps();
        for (String microservice : map.keySet()) {
            MicroserviceManager microserviceManager = map.get(microservice);
            if (Strings.isNullOrEmpty(microKey) || microKey.equals("all")) {//清理所有
                Map<String, MicroserviceVersions> microserviceVersionsMap = microserviceManager.getVersionsByName();
                for (String microserviceVersionKey : microserviceVersionsMap.keySet()) {
                    microserviceManager.getVersionsByName().remove(microserviceVersionKey);
                }
                return;
            }
            //清理指定的
            for (String k : microKey.split(",")) {
                microserviceManager.getVersionsByName().remove(k);
            }
        }
    }

    private JSONObject load() {
        JSONObject resultJson = new JSONObject();
        List<Map<String, Object>> list = getContract();
        resultJson.put("code", "1000");
        JSONObject data = new JSONObject();
        data.put("rows", list.stream().map(JSONObject::new).collect(Collectors.toCollection(JSONArray::new)));
        data.put("totalCount", list.size());
        resultJson.put("data", data);
        resultJson.put("message", "操作成功");
        resultJson.put("rows", "操作成功");
        resultJson.put("success", true);
        resultJson.put("totalCount", list.size());
        return resultJson;
    }

    public List<Map<String, Object>> getContract() {
        List<Map<String, Object>> list = new ArrayList<>();
        //获取service.application
        Map<String, MicroserviceManager> microserviceManagerMap = DiscoveryManager.INSTANCE.getAppManager().getApps();
        for (String key : microserviceManagerMap.keySet()) {
            Map<String, MicroserviceVersions> microserviceVersionsMap = microserviceManagerMap.get(key).getVersionsByName();
            for (String vKey : microserviceVersionsMap.keySet()) {
                MicroserviceVersions microserviceVersions = microserviceVersionsMap.get(vKey);
                buildResultMap(microserviceVersions, list);
            }
        }
        return list;
    }

    private void buildResultMap(MicroserviceVersions microserviceVersions, List<Map<String, Object>> list) {
        List<MicroserviceVersion> versions = new ArrayList<>();
        for (String k : microserviceVersions.getVersions().keySet()) {
            versions.add(microserviceVersions.getVersions().get(k));
        }
        for (MicroserviceVersion microserviceVersion : versions) {
            Map<String, Object> map = new HashMap<>();
            Microservice microservice = microserviceVersion.getMicroservice();
            map.put("SERVICE_ID", microservice.getServiceId());
            map.put("FRAMEWORK", microservice.getFramework().getName() + "-" + microservice.getFramework().getVersion());
            map.put("ENVIRONMENT", microservice.getEnvironment());
            map.put("APP_ID", microservice.getAppId());
            map.put("SERVICE_NAME", microservice.getServiceName());
            map.put("VERSION", microservice.getVersion());
            map.put("LEVEL", microservice.getLevel());
            map.put("SCHEMAS_LENGTH", microservice.getSchemas().size());
            list.add(map);
        }
    }

}
